#include <QTime>
#include "gamewindow.h"
#include "mainwidget.h"

GameWindow::GameWindow(QDeclarativeEngine* eng, int nCake)
{
    myEngine = eng;
    QDeclarativeComponent *component = new QDeclarativeComponent(myEngine, QUrl::fromLocalFile("qml/cakeTower/GameView.qml"));
    myGameScreen = qobject_cast<QDeclarativeItem*>(component->create());
    myGameScreen->setParentItem(this);

    myPlate = myGameScreen->findChild<QDeclarativeItem*>("myplate");
    myOrderList = myGameScreen->findChild<QDeclarativeItem*>("orderlist");
    myscore = myGameScreen->findChild<QDeclarativeItem*>("score");
    mylife = myGameScreen->findChild<QDeclarativeItem*>("life");
    nStack = nCake;
    score = 0;
    life = 3;
    create();
}

GameWindow::~GameWindow()
{
    destroy();

}

void GameWindow::create()
{
    m_lastupdate = 0;
    cakeList.clear();
    generateSoal();
    generateSoal();
    generateSoal();
//    qDebug() << soalCake.size() + " - " + nStack;
    redrawSoal();
    resume();
}

void GameWindow::destroy()
{

}

/*!
  Pauses the execution.
*/
void GameWindow::pause()
{

}

void GameWindow::resume()
{

}

void GameWindow::update(const float frameDelta)
{
//    qDebug() << frameDelta;
    if (m_lastupdate > 1)
    {
        addCake();
        m_lastupdate -= 1;
    }
    updateCake(frameDelta);
    m_lastupdate += frameDelta;
//    qDebug() << getFPS();
    Q_UNUSED(frameDelta);
}

/*!
  Returns the tick count in milliseconds.
*/
unsigned int GameWindow::getTickCount() const
{
    QTime now = QTime::currentTime();
    return (now.hour() * 3600 + now.minute() * 60 + now.second()) * 1000
            + now.msec();
}

void GameWindow::addCake()
{
    QDeclarativeComponent *component2 = new QDeclarativeComponent(myEngine, QUrl::fromLocalFile(contentPath + "Cake.qml"));
    QDeclarativeItem *mycake = qobject_cast<QDeclarativeItem*>(component2->create());
    mycake->setY(100);
    QTime now = QTime::currentTime();
    qsrand((uint)now.msec());
    mycake->setX(((qrand() % 3)* 120) + 10);
    //myGameScreen->findChild<QObject*>("arrayCake");
    //mycake->setParentItem(this);
    mycake->setParentItem(myGameScreen->findChild<QDeclarativeItem*>("arrayCake"));
    mycake->setProperty("tbegin", getTickCount());
    qsrand((uint)now.msec());
//    mycake->setProperty("type", (qrand()%20)+1);
    mycake->setProperty("type", (qrand()%5)+1);
    cakeList.push_front(mycake);
}

void GameWindow::updateCake(float delta)
{
    bool checked = false;
    for (int i =0; i< cakeList.size(); i++)
    {
        if (cakeList[i]->y() < 530)
        {
            float t = cakeList[i]->property("tbegin").toFloat();
            t = (getTickCount() - t)* 0.001f;
            //cakeList.at(i)->setProperty("y", cakeList.at(i)->y() + (100 * delta));
            cakeList.at(i)->setProperty("y", 100+(0.5*50*t*t));
            if (colCakeList.isEmpty())
            {
                if (cekCollision(cakeList.at(i)->property("x").toInt(),
                                 cakeList.at(i)->property("y").toInt(),
                                 cakeList.at(i)->property("width").toInt(),
                                 cakeList.at(i)->property("height").toInt(),
                                 myPlate->property("x").toInt(),
                                 myPlate->property("y").toInt(),
                                 myPlate->property("width").toInt(),
                                 myPlate->property("height").toInt()
                                 ))
                {
                   if (isRightCake(cakeList.at(i)->property("type").toString()))
                   {
                         colCakeList.push_front(cakeList[i]);
                         cakeList.removeOne(colCakeList.first());
                         stackCake(colCakeList.first());
                         //qDebug() << colCakeList.size();
                   }
                   else
                   {
                       if (cakeList.at(i)->property("unchecked").toBool())
                       {
                           life--;
                           mylife->setProperty("text", life);
                           clearPlate();
                           cakeList.at(i)->setProperty("unchecked", false);
                       }
                   }
                }
            }
            else
            {
                if (cekCollision(cakeList.at(i)->property("x").toInt(),
                                 cakeList.at(i)->property("y").toInt(),
                                 cakeList.at(i)->property("width").toInt(),
                                 cakeList.at(i)->property("height").toInt(),
                                 myPlate->property("x").toInt() + colCakeList.first()->x(),
                                 myPlate->property("y").toInt() + colCakeList.first()->y(),
                                 colCakeList.first()->width(),
                                 colCakeList.first()->height()
                                 ))
                {
                     if (isRightCake(cakeList.at(i)->property("type").toString()))
                     {
                         colCakeList.push_front(cakeList[i]);
                         cakeList.removeOne(colCakeList.first());
                         stackCake(colCakeList.first());
                         if (colCakeList.size() == nStack)
                         {
                             score += 500;
                             myscore->setProperty("text", score);
                             clearPlate();
                             qDebug() << "yihaa";
                             nextSoal();
                         }
                     }
                     else
                     {
//                         if (cakeList.at(i)->property("unchecked").toBool())
//                         {
                             colCakeList.push_front(cakeList[i]);
                             cakeList.removeOne(colCakeList.first());
                             stackCake(colCakeList.first());
                             qDebug() << "wrong";
                             life--;
                             mylife->setProperty("text", life);
                             clearPlate();
//                         }
                     }
                }
            }
        }
        else if (cakeList[i]->opacity() <= 0)
        {
            delCakeList.push_front(cakeList[i]);
            //qDebug() << "delete cake";
        }
        else if (cakeList[i]->opacity() == 1)
        {
            cakeList[i]->setProperty("state", "Disapear");
        }
    }
    destroyCake();
//    qDebug() << cakeList.size();
}

void GameWindow::destroyCake()
{
    for (int i =0; i< delCakeList.size();i++)
    {
        cakeList.removeOne(delCakeList[i]);
    }
    delCakeList.clear();
}

bool GameWindow::cekCollision(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)
{
    //
    if ((x1>=x2) && (x1<= (x2+w2)))
    {
        if (((y1 >= y2) && (y1 <= (y2+h2))) || ((y1+h1 >= y2) && (y1+h1 <= (y2+h2))))
            return true;
    }
    else if ((x1+w1 >=x2) && (x1+w1 <= (x2+w2)))
    {
        if (((y1 >= y2) && (y1 <= (y2+h2))) || ((y1+h1 >= y2) && (y1+h1 <= (y2+h2))))
            return true;
    }else if ((x2>=x1) && (x2<= (x1+w1)))
    {
        if (((y2 >= y1) && (y2 <= (y1+h1))) || ((y2+h2 >= y1) && (y2+h2 <= (y1+h1))))
            return true;
    }
    else if ((x2+w2 >=x1) && (x2+w2 <= (x1+w1)))
    {
        if (((y2 >= y1) && (y2 <= (y1+h1))) || ((y2+h2 >= y1) && (y2+h2 <= (y1+h1))))
            return true;
    }
    return false;
}

void GameWindow::stackCake(QDeclarativeItem *cake){
//    QDeclarativeItem *temp = myGameScreen->findChild<QDeclarativeItem*>("myplate");
//    QDeclarativeItem *temp2 = temp->findChild<QDeclarativeItem*>("cole");
    QDeclarativeItem *temp2 = myPlate->findChild<QDeclarativeItem*>("cole");
//    temp2->setParentItem(temp);
    cake->setParentItem(temp2);
    cake->setY(-7 - (colCakeList.size()-1)* 28);
    cake->setX(cake->x() - myPlate->x());
//    myPlate = cake;
    //cake->setParentItem(temp->findChild<QDeclarativeItem*>("cole"));
    cake->setParent(myPlate->findChild<QObject*>("cole"));
    //cake->setX(cake->x() - temp->x());
    //qDebug() << temp->findChild<QDeclarativeItem*>("cole");
    //qDebug() << "haha " <<wawaw->children().size();
}

void GameWindow::generateSoal()
{
    for (int i = 0; i<nStack; i++)
    {
        QTime now = QTime::currentTime();
        qsrand((uint)now.msec());
//        temp->push_front((qrand()%20)+1);
//        mycake->setProperty("type", (qrand()%20)+1);

        QDeclarativeComponent *component2 = new QDeclarativeComponent(myEngine, QUrl::fromLocalFile(contentPath + "CakeOrder.qml"));
        QDeclarativeItem *mycake = qobject_cast<QDeclarativeItem*>(component2->create());
//        mycake->setProperty("type", (qrand()%20)+1);
        mycake->setProperty("type", (qrand()%5)+1);
//        QTime now = QTime::currentTime();
//        qsrand((uint)now.msec());
        soalCake.push_back(mycake);
    }
}

void GameWindow::redrawSoal()
{
    for (int i=0; i<nStack*3;i++)
    {
//        qDebug() << myOrderList->findChild<QDeclarativeItem*>("order0");
        QString ord = "order" + QString::number(i/3);
//        qDebug() << ord;
        soalCake.at(i)->setParentItem(myOrderList->findChild<QDeclarativeItem*>(ord));
        soalCake.at(i)->setParent(myOrderList->findChild<QObject*>(ord));
        soalCake.at(i)->setY(130-(i%3)*30);
//        soalCake.at(i)->setY(130);
    }
}

bool GameWindow::isRightCake(QString type)
{
    return soalCake.at(colCakeList.size())->property("type").toString().toInt() == type.toInt();
}

void GameWindow::nextSoal()
{
    soalCake.removeFirst();
    soalCake.removeFirst();
    soalCake.removeFirst();
    generateSoal();
    redrawSoal();
}

void GameWindow::clearPlate()
{
    int temp = colCakeList.size();
    QDeclarativeItem *temp2 = myPlate->findChild<QDeclarativeItem*>("cole");

    for (int i=0; i<temp; i++)
    {
        colCakeList.removeFirst();
//        qDebug() << temp2->children().pop_front();
    }

//    qDebug() << myPlate->findChild<QDeclarativeItem*>("cole");
//    QDeclarativeItem *temp2 = myPlate->findChild<QDeclarativeItem*>("cole");
    qDebug() << temp2->children().size();
//    temp2->childItems().clear();
    colCakeList.clear();
}
